package com.googlecode.scenemaker3d.controller
{
	import com.googlecode.caurina.transitions.Tweener;
	
	import flash.events.Event;
	
	import com.googlecode.scenemaker3d.model.VO_Object3D;
	import com.googlecode.scenemaker3d.model.World3DModel;
	
	import mx.collections.ArrayCollection;
	import mx.collections.Sort;
	import mx.collections.SortField;
	
	import org.papervision3d.core.math.Number3D;
	
	import com.googlecode.scenemaker3d.view.timeline.GlobalMarker;
	import com.googlecode.scenemaker3d.view.timeline.KeyFrame;
	import com.googlecode.scenemaker3d.view.timeline.SplitMarker;
	import com.googlecode.scenemaker3d.view.timeline.Timeline;
	
	public class TimelineController implements ITimelineController
	{
		private var mWorld:World3DModel;
		
		public function TimelineController(m:World3DModel)
		{
			this.mWorld = m;
		}
		private function checkKeyFramePlacement(time:Number):void
		{
			var VO:VO_Object3D = mWorld.selectedObject;
			var keyFrames:ArrayCollection = VO.keyFrames;
			
			for(var i:uint=0; i<keyFrames.length; i++)
			{
				if(keyFrames[i].time == time)
				{		
					keyFrames.removeItemAt(i);
					break;
				}
			}
		}
		public function insertKeyFrame(time:int = -1, pos:Number3D = null):void
		{		
			var VO:VO_Object3D = mWorld.selectedObject;
			
			if(pos == null)
			{
				pos = mWorld.selectedObjectPos;
			}
			
			if(time < 0)
			{
				time = mWorld.currentTimeInt;
			}
			
			checkKeyFramePlacement(time);
			var k:KeyFrame = new KeyFrame(Timeline.SQUARE_WIDTH, "keyFrame_" + mWorld.keyFrameID);			
			
			k.time = time;
			k.objPos = pos;
			k.object3D = VO;
			
			if(time == 0)
			{
				k.enableDragging = false;
			}
			
			VO.keyFrames.addItem(k);

			mWorld.keyFrameID += 1;
		}
		public function removeKeyFrame(keyFrame:KeyFrame):void
		{
			var VO:VO_Object3D = keyFrame.object3D;
			var keyFrames:ArrayCollection = VO.keyFrames;
			
			for(var i:uint=0; i<keyFrames.length; i++)
			{
				if(keyFrames[i].id == keyFrame.id)
				{
					keyFrames.removeItemAt(i);
					break;
				}
			}
		}
		public function removeAllKeyFrames(VO:VO_Object3D):void
		{
			var keyFrames:ArrayCollection = VO.keyFrames;
			
			for(var i:uint=1; i<keyFrames.length; i++){
				keyFrames.removeItemAt(i);
				i--;
			}
		}
		public function insertHideMarker(yOffset:uint):void
		{
			var VO:VO_Object3D = mWorld.selectedObject; 
			
			var time:uint = mWorld.currentTimeInt;
			var hideMarker:SplitMarker = new SplitMarker(Timeline.SQUARE_WIDTH, Timeline.SQUARE_WIDTH, time, yOffset);
			hideMarker.object3D = VO;
			
			VO.hideMarkers.addItem(hideMarker);		
		}
		public function removeHideMarker(hideMarker:SplitMarker):void
		{
			var VO:VO_Object3D = hideMarker.object3D;
			var hideMarkers:ArrayCollection = VO.hideMarkers;
			
			for(var i:uint=0; i<hideMarkers.length; i++)
			{
				if(hideMarkers[i].id == hideMarker.id)
				{
					hideMarkers.removeItemAt(i);
					break;
				}
			}
		}
		public function removeAllHideMarkers(VO:VO_Object3D):void
		{
			var hideMarkers:ArrayCollection = VO.hideMarkers;
			
			for(var i:uint=0; i<hideMarkers.length; i++){
				hideMarkers.removeItemAt(i);
				i--;
			}
		}
		public function insertGlobalMarker():void
		{
			var time:uint = mWorld.currentTimeInt;
			var globalMarker:GlobalMarker = new GlobalMarker(Timeline.SQUARE_WIDTH, "globalMarker_" + mWorld.globalMarkerID);
			globalMarker.time = time;
			
			mWorld.globalMarkers.addItem(globalMarker);
			
			mWorld.globalMarkerID += 1;
		}
		public function removeGlobalMarker(id:String):void
		{
			var globalMarkers:ArrayCollection = mWorld.globalMarkers;
			
			for(var i:uint=0; i<globalMarkers.length; i++)
			{
				if(globalMarkers[i].id == id)
				{
					globalMarkers.removeItemAt(i);
					break;
				}
			}
		}
		public function removeAllGlobalMarkers():void
		{
			var globalMarkers:ArrayCollection = mWorld.globalMarkers;
			
			for(var i:uint=0; i<globalMarkers.length; i++){
				globalMarkers.removeItemAt(i);
				i--;
			}
		}
		public function calculateTweens(keyFrames:ArrayCollection):void
		{
			var VO:VO_Object3D = mWorld.selectedObject;
			
			//Sort keyFrames time ascending
			var s:Sort = new Sort();
			var sF:SortField = new SortField("time", true);
			sF.numeric = true;				
			s.fields = [sF];
			keyFrames.sort = s;
			keyFrames.refresh();
			
			//Clear tweens
			VO.tweens.removeAll();
			
			//Tween
			if(keyFrames.length < 1)
			{
				return;
			}
			var e:Event = new Event("event");
			var startPos:Number3D = (keyFrames[0].objPos as Number3D).clone();
			VO.tweens.addItem(startPos);
			
			for(var i:uint=0; i<keyFrames.length-1; i++)
			{
				var currentPos:Number3D = (keyFrames[i].objPos as Number3D).clone();
				var nextPos:Number3D = (keyFrames[i+1].objPos as Number3D).clone();
				var t:uint = (keyFrames[i+1].time - keyFrames[i].time) /10;
				
				if(t==0)
				{
					return;
				}
				
				Tweener.addTween(currentPos, {x:nextPos.x, y:nextPos.y, z:nextPos.z, time:t, useFrames:true, transition:"linear"});
				
				for(var j:uint=0; j<t; j++)
				{
					Tweener.onEnterFrame(e);
					VO.tweens.addItem(currentPos.clone());
				}
				
			}
			Tweener.removeTweens(currentPos);
		}
		
		public function set selectedTimeInterval(t:uint):void
		{
			mWorld.currentTimeInt = t;
		}
		
		public function get selectedTimeInterval():uint
		{
			return mWorld.currentTimeInt;
		}
		
	}
}